package com.soft.service;

import java.time.LocalDateTime;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.soft.entity.User;
import com.soft.mapper.UserMapper;

/**
 * 用户领域服务：登录/注册/资料/密码与管理端的用户CRUD。
 * 兼容明文旧密码，命中后自动迁移为BCrypt。
 */
@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;

    private final PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();

    private boolean isBcryptHash(String val) {
        return val != null && val.startsWith("$2a$") || val != null && val.startsWith("$2b$") || val != null && val.startsWith("$2y$");
    }

    public User login(String username, String rawPassword) {
        User user = userMapper.findByUsername(username);
        if (user == null) return null;
        String stored = user.getPassword();
        if (stored == null) return null;

        // 支持明文老数据与 BCrypt 新数据；若匹配到旧明文，则自动迁移为 BCrypt
        boolean ok = isBcryptHash(stored) ? passwordEncoder.matches(rawPassword, stored) : rawPassword.equals(stored);
        if (!ok) return null;

        if (!isBcryptHash(stored)) {
            user.setPassword(passwordEncoder.encode(rawPassword));
            userMapper.updateById(user); // 平滑迁移
        }
        return user;
    }

    public User register(String username, String password, String email, String phone) {
        if (checkUsernameExist(username) || checkEmailExist(email)) {
            return null;
        }
        User user = new User();
        user.setUsername(username);
        user.setPassword(passwordEncoder.encode(password));
        user.setEmail(email);
        user.setNickname("Nickname");
        user.setPhone(phone);
        user.setCreateTime(LocalDateTime.now());
        user.setStatus("active");
        user.setRole("member");
        userMapper.insert(user);
        return user;
    }

    public boolean checkUsernameExist(String username) {
        return userMapper.findByUsername(username) != null;
    }

    public Integer getUserIdByUsername(String username) {
        User user = userMapper.findByUsername(username);
        return user != null ? user.getUserId() : null;
    }

    public Integer getUserIdByEmail(String email) {
        User user = userMapper.findByEmail(email);
        return user != null ? user.getUserId() : null;
    }

    public boolean checkEmailExist(String email) {
        return userMapper.findByEmail(email) != null;
    }

    public String getNicknameByUsername(String username) {
        User user = userMapper.findByUsername(username);
        return user != null ? user.getNickname() : null;
    }

    public String getNicknameByUserId(Integer userId) {
        if (userId == null) { return null; }
        User user = userMapper.selectById(userId);
        return user != null ? user.getNickname() : null;
    }

    public String getEmailByUsername(String username) {
        User user = userMapper.findByUsername(username);
        return user != null ? user.getEmail() : null;
    }

    public String getPhoneByUsername(String username) {
        User user = userMapper.findByUsername(username);
        return user != null ? user.getPhone() : null;
    }

    public String getRoleByUsername(String username) {
        User user = userMapper.findByUsername(username);
        return user != null ? user.getRole() : null;
    }

    public String getStatusByUsername(String username) {
        User user = userMapper.findByUsername(username);
        return user != null ? user.getStatus() : null;
    }

    public LocalDateTime getCreateTimeByUsername(String username) {
        User user = userMapper.findByUsername(username);
        return user != null ? user.getCreateTime() : null;
    }

    public boolean updateNickname(String username, String newNickname) {
        User user = userMapper.findByUsername(username);
        if (user != null) {
            user.setNickname(newNickname);
            return userMapper.updateById(user) > 0;
        }
        return false;
    }

    public boolean updateEmail(String username, String newEmail) {
        if (checkEmailExist(newEmail)) {
            return false;
        }
        User user = userMapper.findByUsername(username);
        if (user != null) {
            user.setEmail(newEmail);
            return userMapper.updateById(user) > 0;
        }
        return false;
    }

    public boolean updatePhone(String username, String newPhone) {
        User user = userMapper.findByUsername(username);
        if (user != null) {
            user.setPhone(newPhone);
            return userMapper.updateById(user) > 0;
        }
        return false;
    }

    public boolean updateRole(String username, String newRole) {
        User user = userMapper.findByUsername(username);
        if (user != null) {
            user.setRole(newRole);
            return userMapper.updateById(user) > 0;
        }
        return false;
    }

    public boolean updateStatus(String username, String newStatus) {
        User user = userMapper.findByUsername(username);
        if (user != null) {
            user.setStatus(newStatus);
            return userMapper.updateById(user) > 0;
        }
        return false;
    }

    public int updatePassword(String username, String oldPassword, String newPassword) {
        User user = userMapper.findByUsername(username);
        if (user == null) {
            return -1; // 用户不存在
        }
        String stored = user.getPassword();
        boolean ok = isBcryptHash(stored) ? passwordEncoder.matches(oldPassword, stored) : oldPassword.equals(stored);
        if (!ok) {
            return 0; // 旧密码错误
        }
        user.setPassword(passwordEncoder.encode(newPassword));
        return userMapper.updateById(user) > 0 ? 1 : -2; // 1:成功 -2:更新失败
    }

    // ============ 管理端：用户管理 ============
    public List<User> listUsers(String keyword) {
        QueryWrapper<User> qw = new QueryWrapper<>();
        if (keyword != null && !keyword.trim().isEmpty()) {
            qw.like("username", keyword).or()
              .like("email", keyword).or()
              .like("phone", keyword).or()
              .like("nickname", keyword);
        }
        qw.orderByDesc("create_time");
        return userMapper.selectList(qw);
    }

    public long countUsers(String keyword) {
        QueryWrapper<User> qw = new QueryWrapper<>();
        if (keyword != null && !keyword.trim().isEmpty()) {
            qw.like("username", keyword).or()
              .like("email", keyword).or()
              .like("phone", keyword).or()
              .like("nickname", keyword);
        }
        return userMapper.selectCount(qw);
    }

    public List<User> listUsersPage(String keyword, int page, int size) {
        int p = Math.max(1, page);
        int s = Math.max(1, Math.min(size, 200));
        int offset = (p - 1) * s;
        QueryWrapper<User> qw = new QueryWrapper<>();
        if (keyword != null && !keyword.trim().isEmpty()) {
            qw.like("username", keyword).or()
              .like("email", keyword).or()
              .like("phone", keyword).or()
              .like("nickname", keyword);
        }
        qw.orderByDesc("create_time").last("limit " + offset + "," + s);
        return userMapper.selectList(qw);
    }

    public User getById(Integer userId) {
        return userId == null ? null : userMapper.selectById(userId);
    }

    public User createUser(String username, String password, String email, String phone, String role, String status) {
        if (username == null || username.trim().isEmpty()) return null;
        if (checkUsernameExist(username)) return null;
        if (email != null && !email.isEmpty() && checkEmailExist(email)) return null;
        User user = new User();
        user.setUsername(username);
        // 管理端创建用户时也要进行哈希
        user.setPassword(password == null || password.isEmpty() ? null : passwordEncoder.encode(password));
        user.setEmail(email);
        user.setPhone(phone);
        user.setNickname("Nickname");
        user.setCreateTime(LocalDateTime.now());
        user.setStatus(status != null ? status : "active");
        user.setRole(role != null ? role : "member");
        userMapper.insert(user);
        return user;
    }

    public boolean updateUserById(User payload) {
        if (payload == null || payload.getUserId() == null) return false;
        User u = userMapper.selectById(payload.getUserId());
        if (u == null) return false;
        if (payload.getNickname() != null) u.setNickname(payload.getNickname());
        if (payload.getEmail() != null) {
            if (!payload.getEmail().equals(u.getEmail()) && checkEmailExist(payload.getEmail())) return false;
            u.setEmail(payload.getEmail());
        }
        if (payload.getPhone() != null) u.setPhone(payload.getPhone());
        if (payload.getRole() != null) u.setRole(payload.getRole());
        if (payload.getStatus() != null) u.setStatus(payload.getStatus());
        if (payload.getPassword() != null && !payload.getPassword().isEmpty()) {
            u.setPassword(passwordEncoder.encode(payload.getPassword()));
        }
        return userMapper.updateById(u) > 0;
    }

    public boolean deleteUserById(Integer userId) {
        if (userId == null) return false;
        return userMapper.deleteById(userId) > 0;
    }
}
